from rest_framework import serializers
from casedemo13_ser.models import Student


# BookSerializer 书本序列器
class BookSerializer(serializers.Serializer):
    title = serializers.CharField()
    price = serializers.IntegerField()
    pub_date = serializers.DateField()

"""
serializers 是drf提供给开发者调用的序列化器模块
里面声明了所有的可用序列化器的基类：
Serializer      序列化器基类，drf中所有的序列化器类都必须继承于 Serializer
ModelSerializer 模型序列化器基类，是序列化器基类的子类，在工作中，除了Serializer基类以外，最常用的序列化器类基类
"""
class Student1Serializer(serializers.Serializer):
    """学生信息序列化器"""
    # 1. 转换的字段声明
    # 字段 = serializers.字段类型(选项=选项值,)
    id = serializers.IntegerField(read_only=True)  # read_only=True, 在客户端提交数据[反序列化阶段不会要求id字段]
    name = serializers.CharField()
    sex = serializers.BooleanField()
    age = serializers.IntegerField()
    description = serializers.CharField()

    def validate_name(self, value):
        if Student.objects.filter(name=value).exists():
            raise serializers.ValidationError("该姓名已存在")
        return value

    def create(self, validated_data):
        return Student.objects.create(**validated_data)

    def update(self, instance, validated_data):
        instance.name = validated_data.get('name', instance.name)
        instance.age = validated_data.get('age', instance.age)
        instance.sex = validated_data.get('sex', instance.sex)
        instance.description = validated_data.get('description', instance.description)
        instance.save()
        return instance

    class Meta:
        fields ="__all__"
        model=Student



class Student1ModelSerializer(serializers.ModelSerializer):
    """学生信息序列化器"""
    # 1. 转换的字段声明
    # 字段 = serializers.字段类型(选项=选项值,)
    id = serializers.IntegerField(read_only=True)  # read_only=True, 在客户端提交数据[反序列化阶段不会要求id字段]
    name = serializers.CharField()
    sex = serializers.BooleanField()
    age = serializers.IntegerField()
    description = serializers.CharField()

    def validate_name(self, value):
        if Student.objects.filter(name=value).exists():
            raise serializers.ValidationError("该姓名已存在")
        return value

    class Meta:
        fields ="__all__"
        model=Student











class Student2Serializer(serializers.Serializer):
    """学生信息序列化器"""
    # 1. 转换的字段声明
    # 字段 = serializers.字段类型(选项=选项值,)
    id = serializers.IntegerField(read_only=True)  # read_only=True, 在客户端提交数据[反序列化阶段不会要求id字段]
    name = serializers.CharField(required=True)  # required=True , 反序列化阶段必填
    sex = serializers.BooleanField(default=True)  # default=True，  反序列化阶段，客户端没有提交，则默认为True
    age = serializers.IntegerField(max_value=100, min_value=0, error_messages={
        "min_value": "The Age Filed Must Be 0 <= age",  # age在反序列化必须是 0 <= age <= 100
        "max_value": "The Age Filed Must Be age <= 100",
    })
    # validators 外部验证函数选项，值是一个列表，列表得到成员是函数名，不能是字符串！！！
    # classmate = serializers.CharField(validators=[check_classmate])
    description = serializers.CharField(allow_null=True, allow_blank=True)  # 允许客户端不填写内容(None)，或者值为 ""


class StudentModelSerializer(serializers.ModelSerializer):
    """学生信息序列化器"""
    # 1. 转换的字段声明
    # 字段名 = 字段类型(选项=选项值)
    nickname = serializers.CharField(read_only=True)
    # 2. 如果当前序列化器继承的是ModelSerializer，则需要声明调用的模型信息
    # 必须给Meta声明2个属性
    class Meta:
        model = Student                                       # 必填
        fields = ["id", "name", "age", "sex","nickname"]      # 必填，可以是字符串和列表/元组，字符串的值只能是"__all__"表示返回所有字段
        read_only_fields = ["id","sex"]  # 选填，只读字段列表，表示设置这里的字段只会在序列化阶段采用
        extra_kwargs = {  # 选填，字段额外选项声明
            "age": {
                "min_value": 5,
                "max_value": 20,
                "error_messages": {
                    "min_value": "年龄的最小值必须大于等于5",
                    "max_value": "年龄的最大值必须小于等于20",
                }
            },
        }